import {
    initState
} from './state'
import {
    compileToFunction
} from './compiler/index.js'

import {
    mountComponent,
    callHook
} from './lifecycle'
import {
    mergeOptions
} from './util/index.js'

export function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        const vm = this
        // vm.$options = options // 配置项
        vm.$options = mergeOptions(vm.constructor.options, options);
        // 初始化状态
        callHook(vm, 'beforeCreate');
        initState(vm) // 初始化状态，将初始化状态代码分割到state.js文件处理

        // 对dom 模板的解析，如果传入el 说明这个vue是挂载到当前el
        if (vm.$options.el) {
            vm.$mount(vm.$options.el)
        }
    }
    Vue.prototype.$mount = function (el) {
        const vm = this
        const options = vm.$options
        // 这里处理的比较简单直接使用querySelector转换为dom 元素
        // 在源码 el 也可以直接是一个dom元素 这里不做过多判断
        el = document.querySelector(el);
        // 关于模板的渲染顺序
        // 默认先会查找有没有render方法，没有render 会 采用template template也没有就用el中的内容
        if (!options.render) {
            // 对模板编译
            let template = options.template
            if (!template && el) {
                // 如果没有template 就使用el 绑定做为template
                template = el.outerHTML
            }
            // 无论是template 还是 el 最后都要转成render的形式
            const render = compileToFunction(template);
            options.render = render;
        }
        // 渲染当前的组件 挂载这个组件
        mountComponent(vm, el);
    }
}